package huaweiod.first;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

/**
 * 华为OD机试真题 Java 实现【任务调度】【2022.11 Q4 新题】
 */
public class A_2023_53_TaskSchedule {

    public static class TaskSchedule {
        int id;
        int prior;
        int exeTime;
        int croTime;

        public TaskSchedule(int id, int prior, int exeTime, int croTime) {
            this.id = id;
            this.prior = prior;
            this.exeTime = exeTime;
            this.croTime = croTime;
        }
    }

    public static void main(String[] args) {
        TaskSchedule task1 = new TaskSchedule(1, 3, 5, 1);
        TaskSchedule task2 = new TaskSchedule(2, 1, 5, 10);
        TaskSchedule task3 = new TaskSchedule(3, 2, 7, 12);
        TaskSchedule task4 = new TaskSchedule(4, 3, 2, 20);
        TaskSchedule task5 = new TaskSchedule(5, 4, 9, 21);
        TaskSchedule task6 = new TaskSchedule(6, 4, 2, 22);

        List<TaskSchedule> list = new ArrayList<>();
        list.add(task1);
        list.add(task2);
        list.add(task3);
        list.add(task4);
        list.add(task5);
        list.add(task6);
        list.sort((a,b) -> a.croTime - b.croTime);

        PriorityQueue<TaskSchedule> pq = new PriorityQueue<>(new Comparator<TaskSchedule>() {
            @Override
            public int compare(TaskSchedule o1, TaskSchedule o2) {
                return o1.prior != o2.prior ? o2.prior - o1.prior : o1.id - o2.id;
            }
        });

        int curTime = 0;
        TaskSchedule curTask = null;
        while (!list.isEmpty() || !pq.isEmpty() || curTask != null) {
            curTime++;
            if(curTask != null) {
                curTask.exeTime = curTask.exeTime - 1;
                if(curTask.exeTime == 0) {
                    System.out.println(curTask.id + " " + curTime);
                    curTask = null;
                }
            }
            // 到达时间任务入队
            for (int i = 0; i < list.size(); i++) {
                TaskSchedule taskSchedule = list.get(i);
                if(taskSchedule.croTime == curTime) {
                    pq.add(taskSchedule);
                    list.remove(i--);
                } else {
                    break;
                }
            }
            // 若队列有任务则，取出任务进行比对
            if(!pq.isEmpty()) {
                if(curTask == null) {
                    curTask = pq.poll();
                } else {
                    if(pq.peek().prior > curTask.prior) {
                        pq.add(curTask);
                        curTask = pq.poll();
                    }
                }
            }
        }
    }
}
